package com.lm.basic;

import com.sun.javafx.runtime.SystemProperties;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.Servlet;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Auther: Min.Liu
 * @Description:
 * @Date: Created in 8:32 2025/3/13
 */
@Slf4j
public class Tomcat {
    private Map<String, Context> ContextMap= new ConcurrentHashMap<>();

    public Map<String, Context> getContextMap() {
        return ContextMap;
    }

    public static void main(String[] args) {
        Tomcat tomcat = new Tomcat();
        tomcat.deployApps();
        tomcat.start(tomcat);
    }

    private void deployApps() {
        //File webapps = new File(System.getProperty("user.dir"), "webapps");
        File target = new File(System.getProperty("user.dir"), "myTomcat\\target");
        for (File file : target.listFiles()) {
            if (file.isDirectory()) {
                deployApp(file);
            }
        }
    }

    private void deployApp(File app) {
        Context context = new Context(app.getName());
        List<File> allFile = getAllFile(app);
        for (File file : allFile) {
            String filePath = file.getPath();
            filePath = filePath.replace(app.getPath() + "\\", "");
            //filePath.replace(".class","");
            filePath = filePath.replace(".class", "");
            filePath = filePath.replace("\\", ".");
            try {
                Class<?> loadClass = Thread.currentThread().getContextClassLoader().loadClass(filePath);
                if (HttpServlet.class.isAssignableFrom(loadClass)) {
                    if (loadClass.isAnnotationPresent(WebServlet.class)) {
                        WebServlet annotation = loadClass.getAnnotation(WebServlet.class);
                        String[] urlPatterns = annotation.urlPatterns();
                        for (String urlPattern : urlPatterns) {
                            //System.out.println(urlPattern);
                            context.addUrlPattern(urlPattern,(Class<Servlet>)loadClass);
                        }
                    }
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
        ContextMap.put(context.getAppname(),context);
    }

    private List<File> getAllFile(File classes) {
        List<File> list = new ArrayList<>();
        for (File file : classes.listFiles()) {
            if (file.isDirectory()) {
                list.addAll(getAllFile(file));
            } else {
                list.add(file);
            }
        }
        return list;
    }

    private void start(Tomcat tomcat) {
        ExecutorService pool = Executors.newFixedThreadPool(10);
        try {
            ServerSocket serverSocket = new ServerSocket(8080);
            while (true) {
                Socket accept = serverSocket.accept();
                pool.execute(new SocketProcessor(accept,tomcat));
            }
        } catch (IOException e) {
            log.error(e.getMessage());
        }

    }
}
